﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Pavilion;

namespace Pavilion
{
    public class AnimationPlayer
    {
        public static int FramesPerSecond = 12;

        public event Action<Animation> Complete;
        public event Action<Frame> FrameChanged;

        public string ResourceName { get; set; }
        public Frame CurrentFrame { get { return animation.FrameList[(int)CurrentFrameIndex]; } }

        private Animation animation;
        private float currentFrameIndex;

        public AnimationPlayer()
        {
            animation = new Animation();
        }

        public void Dispose()
        {
            animation.UnloadAllFrames();
            animation = null;
        }

        public void Animate(GameTime gameTime, float size)
        {
            if (animation == null)
                return;

            if (animation.IsReverse)
                CurrentFrameIndex -= FramesPerSecond * (float)gameTime.ElapsedGameTime.TotalSeconds;
            else
                CurrentFrameIndex += FramesPerSecond * (float)gameTime.ElapsedGameTime.TotalSeconds;
        }

        private void AnimationComplete()
        {
            Reset();
            OnComplete();
        }

        private void Reset()
        {
            if (animation == null)
                return;

            if (animation.IsReverse)
                currentFrameIndex = animation.FrameList.Count - 0.00001f;
            else
                currentFrameIndex = 0f;
        }

        /// <summary>
        /// Gets or sets the current frame Index;
        /// </summary>
        public float CurrentFrameIndex
        {
            get { return currentFrameIndex; }
            set
            {
                if (currentFrameIndex == value)
                    return;

                if ((int)currentFrameIndex == (int)value)
                {
                    currentFrameIndex = value;
                    return;
                }

                currentFrameIndex = value;

                if (IsAnimationComplete)
                    AnimationComplete();

                OnFrameChanged();
            }
        }

        /// <summary>
        /// Gets or sets the animation that is going to be played.
        /// </summary>
        public Animation Animation
        {
            get { return animation; }
            set
            {
                if (animation == value)
                    return;

                animation = value;

                Reset();
            }
        }

        private bool IsAnimationComplete
        {
            get
            {
                if (animation == null)
                    return false;
                if (animation.IsReverse)
                    return (CurrentFrameIndex < 0);
                else
                    return (CurrentFrameIndex > animation.FrameList.Count);
            }
        }

        private void OnFrameChanged()
        {
            if (FrameChanged != null)
                FrameChanged(CurrentFrame);
        }

        private void OnComplete()
        {
            if (Complete != null)
                Complete(Animation);
        }

        public void Draw(Vector2 position, float size, SpriteEffects effects)
        {
            if (animation == null)
                return;

            animation.Draw((int)currentFrameIndex, position, size, effects);
        }
    }
}
